import { FilterDevice, MouseConfigInfo, MouseConfig } from "../types/types";
import { BoardConfig, DpiColorConfig, MouseKey } from "../types/types.v1.d";
import {
  WebHidAPI,
  shiftFrom16Bit,
  shiftTo16Bit,
  shiftLoFrom16Bit,
  shiftHIFrom16Bit,
} from "./WebHidAPI";
import { WebHid } from "./WebHid";
import { MacroList } from "../types/types.v1";
import _ from "lodash";
import { eventCode2Keycode } from "../libs/keycode";
import { getMouseModel, getMouseConfig } from "../config/mouseModels";
import { bufferToHexArray } from "../utils/bufferConverter";

let testApi = null;
declare global {
  interface Window {
    API: typeof testApi;
  }
}
// 扩展 window 接口
export const windowAddFun = () => {
  if (typeof window !== "undefined") {
    window.API = testApi;
  }
};

// 连接设备的HID接口
export const connectDeviceHID = async (
  filters: FilterDevice[] = [],
  deviceName: string = ""
): Promise<DeviceComm | undefined> => {
  const devices = await WebHid.devices(false, filters);
  if (devices.length > 1) {
    const sortDevices = devices.sort((a, b) => a.vendorId - b.vendorId);
    if (deviceName != "") {
      const device = sortDevices.find(
        (device) => device.productName == deviceName
      );
      if (device) {
        testApi = new DeviceComm(new WebHidAPI(device.address));
        windowAddFun();
        return testApi;
      } else {
        return undefined;
      }
    } else {
      testApi = new DeviceComm(new WebHidAPI(sortDevices[0].address));
      windowAddFun();
      return testApi;
    }
  } else if (devices.length == 1) {
    testApi = new DeviceComm(new WebHidAPI(devices[0].address));
    windowAddFun();
    return testApi;
  } else {
    return undefined;
  }
};

// 设备通讯接口
export class DeviceComm {
  api: WebHidAPI;
  vendorId: number = 0;
  productId: number = 0;
  productName: string = "Test Mouse";
  onListeners: Array<{ name: string; fb: Function }> = [];
  mode: string = "usb";

  constructor(api: WebHidAPI) {
    this.api = api;

    const hid = this.api.getHID();

    this.vendorId = hid.vendorId;
    this.productId = hid.productId;
    this.productName = hid.productName;
    this.addListeners();
  }

  addListeners() {
    const fn = (evt: HIDInputReportEvent) => {
      let value = {};
      const data = new Uint8Array(evt.data.buffer);

      if (data[0] == 0xaa && data[1] == 0xfa) {
        // 设备通知数据
        if (data[8] == 0x10) {
          value = { dpi: data[9] - 1, reportRate: data[10] - 1 };
          const listener = this.onListeners.find(
            (listener) => listener.name == "statu"
          );
          listener && listener.fb(value);
        } else if (data[8] == 0x12) {
          value = { profile: data[9] };
          const listener = this.onListeners.find(
            (listener) => listener.name == "profile"
          );
          listener && listener.fb(value);
        } else if (data[8] == 0x50) {
          value = { openApp: data[9] };
          const listener = this.onListeners.find(
            (listener) => listener.name == "openApp"
          );
          listener && listener.fb(value);
        }
      }

      if (data[0] == 0xaa && data[1] == 0x30) {
        value = { battery: data[8], charge_flag: data[9] };
        const listener = this.onListeners.find(
          (listener) => listener.name == "battery"
        );
        listener && listener.fb(value);
      }

      if (data[0] == 0xaa && data[1] == 0xed) {
        value = { mouse_status: data[8] };
        const listener = this.onListeners.find(
          (listener) => listener.name == "mouse_status"
        );
        listener && listener.fb(value);
      }

      if (data[0] == 0x13 && data[1] == 0xe2) {
        const listener = this.onListeners.find(
          (listener) => listener.name == "match"
        );
        listener && listener.fb(value);
      }
    };

    this.api.getHID().addListeners(fn);
  }

  // 获取连接模式
  async getConnectMode() {
    const vid = this.api.getVendorIdId();

    return vid == 0xa8a4 ? "有线连接" : "2.4G连接";
  }

  // 获取版本信息
  async getVersionInfo() {
    const buffer: number[] = new Array(65).fill(0);

    buffer[0] = 0x00;
    buffer[1] = 0x55;
    buffer[2] = 0x03;

    const data: number[] = await this.api.sendDeviceData(buffer);
    let mouseVersion = ""; // ASCII码 '0'=48, '9'=57

    if (data[23] >= 48 && data[23] <= 57) {
      mouseVersion += String.fromCharCode(data[23]);
      mouseVersion += ".";
    } else mouseVersion += "0.";

    if (data[24] >= 48 && data[24] <= 57) {
      mouseVersion += String.fromCharCode(data[24]);
      mouseVersion += ".";
    } else mouseVersion += "0.";

    if (data[25] >= 48 && data[25] <= 57) {
      mouseVersion += String.fromCharCode(data[25]);
    } else mouseVersion += "0";

    return { version: mouseVersion };
  }

  // 获取电量
  async getBatteryInfo() {
    const buffer: number[] = new Array(65).fill(0);

    buffer[0] = 0x00;
    buffer[1] = 0x55;
    buffer[2] = 0x30;
    buffer[3] = 0xa5;
    buffer[4] = 0x0b;
    buffer[5] = 0x2e;
    buffer[6] = 0x01;
    buffer[7] = 0x01;
    buffer[8] = 0x01;

    buffer[9] = 0x00;
    buffer[10] = 0x00;

    // 新实现：事件监听 + Promise封装
    return new Promise<{ battery_value: number; charge_flag: number }>(
      (resolve, reject) => {
        // 一次性事件监听器
        const batteryListener = {
          name: "battery", // 改为"battery"以匹配事件分发逻辑
          fb: (value: any) => {
            // 收到目标数据后，resolve并清理监听器
            console.log("[getBatteryInfo] 收到目标数据:", value);
            // 从监听器数组中移除这个临时监听器
            this.onListeners = this.onListeners.filter(
              (l) => l.name !== "battery"
            );
            resolve({
              battery_value: value.battery,
              charge_flag: value.charge_flag,
            });
          },
        };

        // 注册临时监听器
        this.onListeners.push(batteryListener);

        // 发送请求
        this.api.sendDeviceData(buffer).catch((error) => {
          this.onListeners = this.onListeners.filter(
            (l) => l.name !== "battery"
          );
          reject(error);
        });
      }
    );
  }

  // 获取鼠标按键配置信息
  async getMouseKeys() {
    const TOTAL_KEYS = 18;
    const KEYS_PER_PACKET = 14;
    const FRAME_COUNT = Math.ceil(TOTAL_KEYS / KEYS_PER_PACKET);

    const combinedData = new Array(TOTAL_KEYS * 4).fill(0);

    for (let frame = 0; frame < FRAME_COUNT; frame++) {
      const buffer: number[] = new Array(65).fill(0);

      buffer[0] = 0x00;
      buffer[1] = 0x55;
      buffer[2] = 0x08;
      buffer[3] = 0xa5;
      buffer[4] = 0x0b;
      // 从0x20开始，每帧偏移56字节
      const baseAddr = 0x20 + frame * KEYS_PER_PACKET * 4;
      buffer[5] = baseAddr & 0xff; // ADDR_L
      buffer[6] = (baseAddr >> 8) & 0xff; // ADDR_H
      buffer[7] = 0x00; // reserved
      buffer[8] = (frame & 0x0f) << 4; // Frame|Profile (profile=0)
      buffer[9] = 0x00;
      buffer[10] = 0x00;

      const resp = await this.api.sendDeviceData(buffer);
      if (!(resp && resp.length >= 9 && resp[0] === 0xaa && resp[1] === 0x08)) {
        console.warn("getMouseKeys: invalid resp on frame", frame);
        continue;
      }

      const data = resp.slice(8);
      const copyLen = Math.min(56, (TOTAL_KEYS - frame * KEYS_PER_PACKET) * 4);
      for (let i = 0; i < copyLen; i++) {
        combinedData[frame * 56 + i] = data[i] || 0;
      }

      // 避免设备连续读压力
      if (frame < FRAME_COUNT - 1) {
        await new Promise((r) => setTimeout(r, 10));
      }
    }

    const mouseKeys: MouseKey[] = [];
    for (let index = 0; index < TOTAL_KEYS; index++) {
      mouseKeys.push({
        index,
        keyValue: index,
        keyName: "",
        lang: "",
        type: combinedData[index * 4],
        code1: combinedData[index * 4 + 1],
        code2: combinedData[index * 4 + 2],
        code3: combinedData[index * 4 + 3],
      });
    }

    return mouseKeys;
  }

  // 设置灯光模式
  async setLightMode(lightMode: number) {
    const buffer: number[] = new Array(65).fill(0);

    buffer[0] = 0x00;
    buffer[1] = 0x55;
    buffer[2] = 0x21;
    buffer[3] = 0x00;
    buffer[4] = 0x00;
    buffer[5] = 0x03;
    buffer[6] = 0x00;
    buffer[7] = 0x00;
    buffer[8] = 0x00;

    buffer[9] = 0x00;
    buffer[10] = 0x00;
    buffer[11] = lightMode;

    await this.api.sendDeviceData(buffer);
  }

  // 添加辅助函数来验证和限制DPI值
  validateDpiValue(value: number): number {
    const MIN_DPI = 50;
    const MAX_DPI = 50000;
    if (isNaN(value) || value < MIN_DPI) return MIN_DPI;
    if (value > MAX_DPI) return MAX_DPI;
    return value;
  }

  // 获取鼠标配置信息
  async getMouseConfigInfo() {
    const buffer: number[] = new Array(65).fill(0);

    buffer[0] = 0x00;
    buffer[1] = 0x55;
    buffer[2] = 0x0e;
    buffer[3] = 0xa5;
    buffer[4] = 0x0b;
    buffer[5] = 0x2e;
    buffer[6] = 0x01;
    buffer[7] = 0x01;
    buffer[8] = 0x01;

    buffer[9] = 0x00;
    buffer[10] = 0x00;

    const data = await this.api.sendDeviceData(buffer);
    if (
      (data[13] == 0x00 && data[14] == 0x00 && data[15] == 0x00) ||
      (data[13] == 0xff && data[14] == 0xff && data[15] == 0xff)
    ) {
      return {
        light_mode: 0,
        report_rate: 3,
        profile_index: 0,
        dpi_index: 2,
        dpi_flag: 6,
        dpi_count: 6,
        dpi1_value: 800,
        dpi2_value: 1600,
        dpi3_value: 2400,
        dpi4_value: 3200,
        dpi5_value: 5000,
        dpi6_value: 12000,
        scroll_flag: 0,
        lod_value: 1,
        sensor_flag: 53,
        key_respond: 8,
        sleep_light: 10,
        highspeed_mode: 0,
        wakeup_flag: 0,
      } as MouseConfigInfo;
    } else {
      return {
        profile_index: data[8], // TODO
        light_mode: data[9], // TODO
        report_rate: data[10] - 1,
        dpi_index: data[12] - 1 > 0 ? data[12] - 1 : 0,
        dpi_flag: data[11],
        dpi_count: data[11],
        dpi1_value: this.validateDpiValue(shiftTo16Bit([data[13], data[14]])),
        dpi2_value: this.validateDpiValue(shiftTo16Bit([data[15], data[16]])),
        dpi3_value: this.validateDpiValue(shiftTo16Bit([data[17], data[18]])),
        dpi4_value: this.validateDpiValue(shiftTo16Bit([data[19], data[20]])),
        dpi5_value: this.validateDpiValue(shiftTo16Bit([data[21], data[22]])),
        dpi6_value: this.validateDpiValue(shiftTo16Bit([data[23], data[24]])),

        scroll_flag: data[48],
        lod_value: data[49],
        sensor_flag: data[50],
        key_respond: data[51],
        sleep_light: data[52],
        highspeed_mode: data[53],
        wakeup_flag: (data[54] >> 4) & 0x0f, // 提取高4位
        move_light_flag: data[54] & 0x0f, // 提取低4位
      } as MouseConfigInfo;
    }
  }

  // 计算校验和（CS字段）
  private calculateChecksum(data: number[], startIndex: number): number {
    // CS后续字节的累加和，只保留低字节
    let sum = 0;

    for (let i = startIndex; i < data.length; i++) {
      sum += data[i];
    }
    return sum & 0xff;
  }

  // 设置按键数据 - 自动分包发送（无需外部传入index/profile）
  async setMouseKeys(keys: MouseKey[], profileIndex: number = 0) {
    console.log("setMouseKeys", keys);

    // 确保按键数组不为空
    if (!keys || keys.length === 0) {
      throw new Error("Keys array cannot be empty");
    }

    // 每包最多处理14个按键（14 * 4 = 56字节数据）
    const KEYS_PER_PACKET = 14;
    const keyChunks: MouseKey[][] = [];

    // 将按键分包
    for (let i = 0; i < keys.length; i += KEYS_PER_PACKET) {
      keyChunks.push(keys.slice(i, i + KEYS_PER_PACKET));
    }

    // 逐包发送
    for (let frameNumber = 0; frameNumber < keyChunks.length; frameNumber++) {
      const keyChunk = keyChunks[frameNumber];
      await this.sendKeyPacket(keyChunk, frameNumber, profileIndex);

      // 发包间隔，避免设备处理不过来
      if (frameNumber < keyChunks.length - 1) {
        await new Promise((resolve) => setTimeout(resolve, 10));
      }
    }
  }

  // 发送单个按键数据包
  private async sendKeyPacket(
    keys: MouseKey[],
    frameNumber: number,
    profileIndex: number
  ) {
    const KEYS_PER_PACKET = 14; // 每包最多14个按键
    const packet: number[] = new Array(64).fill(0);
    packet[0] = 0x00; // reportId
    packet[1] = 0x55; // FLAG - PC发送固定为0x55
    packet[2] = 0x09; // CMD - 按键设置命令
    packet[3] = 0x01; // Mouse/KB - 01表示鼠标
    packet[4] = 0x00; // CS - 校验和，稍后计算

    // 数据长度：每个按键4字节
    const dataLength = keys.length * 4;
    packet[5] = dataLength; // LEN - 数据部分长度

    // 操作地址（小端序）：以帧序号作为偏移，步长=每包数据字节数
    const baseAddr = frameNumber * KEYS_PER_PACKET * 4;
    packet[6] = baseAddr & 0xff; // ADDR_L
    packet[7] = (baseAddr >> 8) & 0xff; // ADDR_H

    // Frame|Profile字节：高4位Frame number，低4位Profile index（由参数传入）
    const sanitizedProfileIndex = profileIndex & 0x0f; // 仅保留低4位
    packet[8] = ((frameNumber & 0x0f) << 4) | (sanitizedProfileIndex & 0x0f);

    // 填充按键数据
    let dataIndex = 9;
    for (let i = 0; i < keys.length; i++) {
      const key = keys[i];
      packet[dataIndex++] = key.type;
      packet[dataIndex++] = key.code1;
      packet[dataIndex++] = key.code2;
      packet[dataIndex++] = key.code3;
    }

    // 计算并设置校验和：从LEN开始到数据末尾
    packet[4] = this.calculateChecksum(packet, 5);
    console.log("Packet data:", packet.slice(0, dataIndex));

    // 发送数据包
    try {
      await this.api.sendDeviceData(packet);
    } catch (error) {
      console.error(`Failed to send key packet ${frameNumber}:`, error);
    }
  }

  // 重置所有按键数据
  async resetAllMouseKeys() {
    // 加载默认配置并使用分包方式写入设备
    const config = await this.loadDefaultConfig();

    if (config && Array.isArray(config.keys)) {
      await this.setMouseKeys(config.keys);
    }
  }

  // 设置鼠标配置
  async setMouseConfigData(data: MouseConfigInfo, profile_index?: number) {
    const buffer: number[] = new Array(65).fill(0);

    buffer[0] = 0x00;
    buffer[1] = 0x55;
    buffer[2] = 0x0f;
    buffer[3] = 0xae;
    buffer[4] = 0x0a;
    buffer[5] = 0x30;
    buffer[6] = 0x01;
    buffer[7] = 0x01;
    buffer[8] = 0x01;

    buffer[9] = profile_index || data.profile_index;
    buffer[10] = data.light_mode; // 灯光模式

    buffer[11] = data.report_rate + 1;
    buffer[12] = data.dpi_count;
    buffer[13] = data.dpi_index + 1;
    buffer[14] = shiftLoFrom16Bit(data.dpi1_value);
    buffer[15] = shiftHIFrom16Bit(data.dpi1_value);
    buffer[16] = shiftLoFrom16Bit(data.dpi2_value);
    buffer[17] = shiftHIFrom16Bit(data.dpi2_value);
    buffer[18] = shiftLoFrom16Bit(data.dpi3_value);
    buffer[19] = shiftHIFrom16Bit(data.dpi3_value);
    buffer[20] = shiftLoFrom16Bit(data.dpi4_value);
    buffer[21] = shiftHIFrom16Bit(data.dpi4_value);
    buffer[22] = shiftLoFrom16Bit(data.dpi5_value);
    buffer[23] = shiftHIFrom16Bit(data.dpi5_value);
    buffer[24] = shiftLoFrom16Bit(data.dpi6_value);
    buffer[25] = shiftHIFrom16Bit(data.dpi6_value);

    buffer[49] = data.scroll_flag;
    buffer[50] = data.lod_value;
    buffer[51] = data.sensor_flag;
    buffer[52] = data.key_respond;
    buffer[53] = data.sleep_light;
    buffer[54] = data.highspeed_mode;
    // buffer[55] 位字段布局: [7-4位:wakeup_flag] [3-0位:move_light_flag]
    buffer[55] = (data.wakeup_flag << 4) | data.move_light_flag;

    await this.api.sendDeviceData(buffer);
  }

  async getMacroData() {
    let bytesP = [];
    for (let offset = 0; offset < 4096; offset += 56) {
      const size = Math.min(4096 - offset, 56);

      bytesP.push(
        this.api.getDeviceData([0x06, 0x0c, size, ...shiftFrom16Bit(offset)])
      );
    }

    const allBytes = await Promise.all(bytesP);
    const macroData = allBytes.flatMap((bytes) => bytes.slice(8));

    return macroData.slice(0, 4096);
  }

  async setMacro(macroList: MacroList[], profileIndex: number = 0) {
    const macroAddr = new Array(64).fill(0);
    let macroContentSize = 0;
    const newMacroList: any = [];

    macroList.map((macroProfile, index) => {
      const newMacroActions: any = [];
      for (let i = 0; i < macroProfile.actions.length; i++) {
        const action = macroProfile.actions[i];
        if (action.type == 1) {
          const code = eventCode2Keycode(action.webCode || "");
          newMacroActions.push({ code, action: action.action, delay: 0 });
        }
        if (action.type == 3) {
          let code = 0x01;
          if (action.webCode == "0") {
            code = 0x01;
          } else if (action.webCode == "1") {
            code = 0x04;
          } else if (action.webCode == "2") {
            code = 0x02;
          } else if (action.webCode == "3") {
            code = 0x08;
          } else if (action.webCode == "4") {
            code = 0x10;
          }
          newMacroActions.push({ code, action: action.action, delay: 0 });
        }

        if (action.type == 2) {
          const last: number = newMacroActions.length - 1;
          if (last >= 0) {
            newMacroActions[last] = {
              ...newMacroActions[last],
              delay: newMacroActions[last].delay + (action?.delay || 10),
            };
          }
        }
      }

      newMacroList.push({
        type: macroProfile.type,
        list: newMacroActions,
      });

      if (newMacroActions.length) {
        const addr = shiftFrom16Bit(macroContentSize + 68);
        macroAddr[index * 2] = addr[0];
        macroAddr[index * 2 + 1] = addr[1];
        macroContentSize += newMacroActions.length * 4;
      } else {
        macroAddr[index * 2] = 0x40;
        macroAddr[index * 2 + 1] = 0x00;
      }
    });

    const macroContent = new Array(macroContentSize).fill(0);
    let macroActionOffset = 0;

    newMacroList.map((macroProfile: any) => {
      macroProfile.list.map((macroAction: any, actionIndex: number) => {
        const offset = shiftFrom16Bit(macroAction.delay || 2);
        const end = actionIndex == macroProfile.list.length - 1 ? 1 : 0;
        const action =
          macroAction.action == "keydown" || macroAction.action == "mousedown"
            ? 1
            : 0;
        const type =
          (macroAction.code >= 0xe0
            ? 1
            : macroAction.action == "mousedown" ||
              macroAction.action == "mouseup"
            ? 3
            : 2) |
          (action << 6) |
          (end << 7);

        macroContent[macroActionOffset] = offset[0];
        macroContent[macroActionOffset + 1] = offset[1];
        macroContent[macroActionOffset + 2] = type;
        macroContent[macroActionOffset + 3] =
          macroAction.code >= 0xe0
            ? 0x1 << (macroAction.code & 0x0f)
            : macroAction.code;
        macroActionOffset += 4;
      });
    });

    const data = [...macroAddr, 0, 0, 0x80, 0, ...macroContent];
    const layerSize = 2048;
    const dataSlice = _.chunk(data, 56);

    for (let index = 0; index < dataSlice.length; index++) {
      const offset = shiftFrom16Bit(profileIndex * layerSize + index * 56);
      const dataArr = [
        dataSlice[index].length,
        offset[0],
        offset[1],
        0x0,
        ...dataSlice[index],
      ];
      const checkSum = dataArr.reduce((p, c) => p + c) & 0xff;

      await this.api.sendDeviceData([
        0x00,
        0x55,
        0x0d,
        0x0,
        checkSum,
        ...dataArr,
      ]);
    }
    //debugger
    await this.api.sendDeviceData([
      0x00, 0x55, 0x10, 0xa5, 0x22, 0x00, 0x00, 0x00, 0x05,
    ]);
  }

  async setMacroData(macroData: number[]) {
    const dataLength = macroData.length;
    if (dataLength > 4096) {
      //throw new Error("macro size error: " + dataLength);
    }
    //await this.resetMacroData();
    const bufferSize = 56;
    for (let offset = 0; offset < dataLength; offset += bufferSize) {
      const buffer = macroData.slice(
        offset,
        Math.min(offset + bufferSize, dataLength)
      );
      await this.api.sendDeviceData([
        0x00,
        0x55,
        0x0d,
        0x0,
        0x0,
        buffer.length,
        ...shiftFrom16Bit(offset),
        0x0,
        ...buffer,
      ]);
    }
    await this.api.sendDeviceData([
      0x00, 0x55, 0x10, 0xa5, 0x22, 0x00, 0x00, 0x00, 0x05,
    ]);
  }

  async resetMacroData() {
    await this.api.sendDeviceData([0x06, 0x0f, 0x04]);
  }

  async loadDefaultConfig(): Promise<MouseConfig> {
    try {
      // 获取鼠标型号配置
      const mouseModel = getMouseModel(this.productName);
      console.log("displayName", mouseModel.displayName);

      // 加载配置文件
      const defaultConfig = await getMouseConfig(mouseModel);

      if (!defaultConfig || !defaultConfig.default) {
        throw new Error(
          `Invalid config file format for ${mouseModel.displayName}`
        );
      }

      return {
        keysLayout: defaultConfig.default.keysLayout,
        keys: defaultConfig.default.DefaultProfile.mouseKeys,
        config: defaultConfig.default.DefaultProfile.defaultConfig,
        dpi: defaultConfig.default.dpi,
        dpiConfig: defaultConfig.default.dpiConfig,
      };
    } catch (error) {
      console.error("Failed to load mouse config:", error);
    }
  }

  /**
   * 0x62 - 下发DPI颜色，GRB顺序
   * @param config DPI颜色配置
   */
  async setDpiColors(config: DpiColorConfig): Promise<void> {
    const buffer: number[] = new Array(65).fill(0);

    buffer[0] = 0x00;
    buffer[1] = 0x55;
    buffer[2] = 0x62;
    buffer[3] = 0xa5;
    buffer[4] = 0x0b;
    buffer[5] = 0x24;
    buffer[6] = 0x01;
    buffer[7] = 0x01;
    buffer[8] = 0x01;

    // Data[0-35]: uint8_t grb[2][6][3] - 2种模式，6个档位，3个颜色通道 (位置9-44)
    let dataIndex = 9;

    for (let mode = 0; mode < 2; mode++) {
      for (let level = 0; level < 6; level++) {
        for (let color = 0; color < 3; color++) {
          buffer[dataIndex++] = config.colors[mode]?.[level]?.[color] || 0;
        }
      }
    }

    await this.api.sendDeviceData(buffer);
  }

  /**
   * 0x63 - 读DPI颜色，GRB顺序
   * @returns DPI颜色配置
   */
  async getDpiColors(): Promise<DpiColorConfig> {
    const buffer: number[] = new Array(65).fill(0);

    buffer[0] = 0x00;
    buffer[1] = 0x55;
    buffer[2] = 0x63;
    buffer[3] = 0xa5;
    buffer[4] = 0x0b;
    buffer[5] = 0x24;
    buffer[6] = 0x01;
    buffer[7] = 0x01;
    buffer[8] = 0x01;

    const data = await this.api.sendDeviceData(buffer);

    if (data[0] == 0xaa && data[1] == 0x63) {
      const colors: number[][][] = [];
      let dataIndex = 8;

      for (let mode = 0; mode < 2; mode++) {
        colors[mode] = [];
        for (let level = 0; level < 6; level++) {
          colors[mode][level] = [];
          for (let color = 0; color < 3; color++) {
            colors[mode][level][color] = data[dataIndex++];
          }
        }
      }

      return { colors };
    }
  }

  /**
   * 0x24 - 设置板载配置 data[0]：当前配置（0-4），data[1]：配置数量（1-5）
   * @returns 板载配置
   */
  async setBoardConfig(config: BoardConfig): Promise<void> {
    const buffer: number[] = new Array(65).fill(0);

    buffer[0] = 0x00; // reportId
    buffer[1] = 0x55; // FLAG - PC发送固定为0x55
    buffer[2] = 0x24; // CMD - 设置板载配置命令
    buffer[3] = 0xa5; // Mouse/KB - 01表示鼠标
    buffer[4] = 0x0b; // CS - 校验和，稍后计算
    buffer[5] = 0x0a; // LEN - 数据部分长度
    buffer[6] = 0x00; // ADDR_L
    buffer[7] = 0x00; // ADDR_H
    buffer[8] = 0x00; // reserved

    buffer[9] = config.currentProfileIndex;
    buffer[10] = config.profileCount;

    await this.api.sendDeviceData(buffer);
  }

  /**
   * 0x25 - 读取板载配置 data[0]：当前配置（0-4），data[1]：配置数量（1-5）
   * @returns 板载配置
   */
  async getBoardConfig(): Promise<BoardConfig> {
    const buffer: number[] = new Array(65).fill(0);

    buffer[0] = 0x00;
    buffer[1] = 0x55;
    buffer[2] = 0x25;
    buffer[3] = 0xa5;
    buffer[4] = 0x0b;
    buffer[5] = 0x0a;
    buffer[6] = 0x00;
    buffer[7] = 0x00;
    buffer[8] = 0x00;

    const data = await this.api.sendDeviceData(buffer);
    const dataIndex = 8;

    if (data[0] == 0xaa && data[1] == 0x25) {
      return {
        currentProfileIndex: data[dataIndex],
        profileCount: data[dataIndex + 1],
      };
    }
  }
}
